性能优化是前端工程化中老生常谈的话题,随着项目越来越庞大,稍不注意就会产生明显的性能问题。而在不同的场景中,我们对于项目性能的关注点是不一样的。在项目开发阶段,我们更关注开发体验,注重项目构建性能;而在生产环境中,我们一般更看重项目在的线上运行时性能。关于开发阶段的构建性能问题,Vite 内部已经做了相当多的优化,实现了项目秒级启动与毫秒级热更新,这部分的具体实现就不属于本文讨论的范畴了,我们会在小册的「源码精读篇」来展开分析。本文所介绍的性能优化主要指线上环境的项目加载性能优化,与页面的 FCP、TTI 这些指标息息相关。
对于项目的加载性能优化而言,常见的优化手段可以分为下面三类:
- 网络优化。包括
HTTP2、DNS 预解析、Preload、Prefetch等手段。 - 资源优化。包括
构建产物分析、资源压缩、产物拆包、按需加载等优化方式。 - 预渲染优化,本文主要介绍
服务端渲染(SSR)和静态站点生成(SSG)两种手段。
而无论是以上哪一类优化方式,都离不开构建工具的支持,也就是说,在这些性能优化的场景中,我们将高频地使用到 Vite,对 Vite 本身的构建能力进行深度地应用或者定制。那么,在接下来的内容中,我们将按照如上的三个部分来分别介绍 Vite 的性能优化知识,并进行代码实操。当然,在之前的章节中,我们已经对于其中的部分优化手段进行了详细地拆解,因此,这一节的内容你既可以当做 Vite 知识点的查漏补缺,也可以作为之前小册内容的回顾和复盘。
# 一、网络优化
# 1. HTTP2
传统的 HTTP 1.1 存在队头阻塞的问题,同一个 TCP 管道中同一时刻只能处理一个 HTTP 请求,也就是说如果当前请求没有处理完,其它的请求都处于阻塞状态,另外浏览器对于同一域名下的并发请求数量都有限制,比如 Chrome 中只允许 6 个请求并发(这个数量不允许用户配置),也就是说请求数量超过 6 个时,多出来的请求只能排队、等待发送。
因此,在 HTTP 1.1 协议中,队头阻塞和请求排队问题很容易成为网络层的性能瓶颈。而 HTTP 2 的诞生就是为了解决这些问题,它主要实现了如下的能力:
- 多路复用。将数据分为多个二进制帧,多个请求和响应的数据帧在同一个 TCP 通道进行传输,解决了之前的队头阻塞问题。而与此同时,在 HTTP2 协议下,浏览器不再有同域名的并发请求数量限制,因此请求排队问题也得到了解决。
- Server Push,即服务端推送能力。可以让某些资源能够提前到达浏览器,比如对于一个 html 的请求,通过 HTTP 2 我们可以同时将相应的 js 和 css 资源推送到浏览器,省去了后续请求的开销。
在 Vite 中,我们可以通过vite-plugin-mkcert在本地 Dev Server 上开启 HTTP2:
pnpm i vite-plugin-mkcert -D
然后在 Vite 配置中进行使用:
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import mkcert from "vite-plugin-mkcert";
export default defineConfig({
plugins: [react(), mkcert()],
server: {
// https 选项需要开启
https: true,
},
});
插件的原理也比较简单,由于 HTTP2 依赖 TLS 握手,插件会帮你自动生成 TLS 证书,然后支持通过 HTTPS 的方式启动,而 Vite 会自动把 HTTPS 服务升级为 HTTP2。
其中有一个特例,即当你使用 Vite 的 proxy 配置时,Vite 会将 HTTP2 降级为 HTTPS,不过这个问题你可以通过vite-plugin-proxy-middleware插件解决。
